home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / PictInfoTest / PictInfoTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-28  |  11.5 KB  |  476 lines  |  [TEXT/KAHL]

  1. // Sample to demonstrate using the Picture Utilities Package
  2. //
  3. // The guts of this is in the window creation function: DoCreateWindow( PicHandle thePicture )
  4. // 
  5. // DoCreateWindow is passed a picture handle and if the global gUsePictPalette is set it
  6. // will use the pict utils package (PUP) to get the color table stored in the pict.  You could 
  7. // this source to sample direct color images, but to keep things as clear as possible this
  8. // application only deals with 8 bit images.
  9. //
  10. // We use the PUP to get the color table for the image.  This is passed into NewGWorld and it
  11. // is also used to create a palette that is attached to the window.
  12. //
  13. // Note that we use PUP to sample the image that was stored in the file.  We interrogate a
  14. // PicHandle read directly from the file.  There are also routines for sampling PixMaps,
  15. // but dont forget that if you are in an indexed color environment, and you sample a PixMap, 
  16. // if you didnt set up the color environment when your first created the PixMap, the colors
  17. // may not be as you expect.  
  18. //
  19. // To see an example of this there are two 8-bit images included with this snippet.
  20. // One is a spectral ramp, the other a green/brow ramp.  Both have approx 120 or so colors.
  21. // to see an example of what PUP may report if you didnt set the colors for a window up
  22. // properly before displaying open one of the files with the "use picture palette" item 
  23. // from the palette menu toggled off.
  24. //
  25. // in this case it will use the "wrong" set of colors to try to draw the image (it just uses
  26. // what ever the default system color table is).  If you get PUP to sample (by toggling on
  27. // the "use picture palette" item from the palette menu the picture is rendered correctly.
  28. //
  29. // Nick Thompson - May 6th 1994
  30. //
  31. //    Copyright:    © 1989-94 by Apple Computer, Inc., all rights reserved.
  32.  
  33. /* Constant Declarations */
  34. #include <menus.h>
  35. #include <PictUtil.h>
  36. #include <QDOffScreen.h>
  37.  
  38.  
  39. #define    WWIDTH        470
  40. #define    WHEIGHT        330
  41.  
  42. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  43. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  44.  
  45. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  46. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  47.  
  48.  
  49.  
  50. enum {
  51.     mApple = 128,
  52.     mFile,
  53.     mPalette
  54. } ;
  55.  
  56. enum {
  57.     iAbout = 1
  58. } ;
  59. enum {
  60.     iOpen = 1,
  61.     iClose,
  62.     iUnused1,
  63.     iQuit = 4
  64. } ;
  65.  
  66. enum {
  67.     iUsePictPalette = 1
  68. } ;
  69.  
  70. static Boolean gQuitFlag = false ;
  71. static Point gStaggerPos = {50,50} ;
  72. static Boolean gUsePictPalette = true ;
  73.  
  74. // function prototypes
  75.  
  76. void InitToolbox( void ) ;
  77. void MainEventLoop( void ) ;
  78. void HandleKeyPress(EventRecord *event) ;
  79. void HandleOSEvent(EventRecord *event) ;
  80. void HandleMenuCommand(long menuResult) ;
  81. PicHandle DoReadPICT( short theRef, OSErr *theErr ) ;
  82. OSErr DoCreateWindow( PicHandle thePicture ) ;
  83. void AdjustMenus( void ) ;
  84.  
  85.  
  86. const RGBColor    kRGBBlack = {0, 0, 0};
  87. const RGBColor    kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
  88.  
  89.  
  90. main()
  91. {
  92.     InitToolbox() ;
  93.     
  94.     MainEventLoop();
  95. }
  96.  
  97.  
  98.  
  99. void InitToolbox()
  100. {
  101.     OSErr         retCode;
  102.     long         gestResponse;
  103.     Handle        menuBar = nil;
  104.     EventRecord event;
  105.     short        count;
  106.  
  107.  
  108.     InitGraf((Ptr) &qd.thePort);
  109.     InitFonts();
  110.     InitWindows();
  111.     InitMenus();
  112.     TEInit();
  113.     InitDialogs(0L);
  114.     InitCursor();
  115.  
  116.     // initialize application globals
  117.     
  118.     gQuitFlag = false;
  119.     
  120.     
  121.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  122.     
  123.     if ( menuBar == nil )
  124.          ExitToShell();                        // if we dont have it then quit - your app 
  125.                                              // needs a dialog here
  126.  
  127.     SetMenuBar(menuBar);                    // Install menus
  128.     DisposHandle(menuBar);
  129.     
  130.     AddResMenu(GetMHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  131.  
  132.     DrawMenuBar();
  133. }
  134.  
  135.  
  136. void MainEventLoop()
  137. {
  138.     EventRecord     event;
  139.     WindowPtr       window;
  140.     short           thePart;
  141.     Rect            screenRect;
  142.     Point            aPoint = {100, 100};
  143.     GWorldPtr        theNewWorld ;
  144.     PixMapHandle    offPixMap ;
  145.     GrafPtr            oldPort ;
  146.  
  147.     while( !gQuitFlag )
  148.     {
  149.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  150.         {
  151.             AdjustMenus() ;
  152.  
  153.             switch (event.what) {
  154.                 case mouseDown:
  155.                 
  156.                     thePart = FindWindow( event.where, &window );
  157.                     
  158.                     switch( thePart ) {
  159.                         case inMenuBar: 
  160.                             HandleMenuCommand(MenuSelect(event.where));
  161.                             break;
  162.                         
  163.                         case inDrag:
  164.                     
  165.                             screenRect = (**GetGrayRgn()).rgnBBox;
  166.                             DragWindow( window, event.where, &screenRect );
  167.                             break ;
  168.                     
  169.                         case inContent:
  170.                     
  171.                             if (window != FrontWindow())
  172.                                 SelectWindow( window );
  173.                             break ;
  174.                     
  175.                         case inGoAway:
  176.                             if (TrackGoAway( window, event.where )) {
  177.                                 DisposeWindow ( window );
  178.                             }
  179.                             break ;
  180.                             
  181.                         default:
  182.                             break ;
  183.                     }
  184.                     break ;
  185.                             
  186.                         
  187.                 case updateEvt:
  188.                 
  189.                     window = (WindowPtr)event.message;
  190.                     GetPort(&oldPort ) ;    
  191.                     SetPort( window );
  192.                     
  193.                     BeginUpdate( window );
  194.                     
  195.                     // get the GWorld from the window refcon
  196.                     theNewWorld = (GWorldPtr)GetWRefCon ( window );
  197.                     offPixMap = GetGWorldPixMap( theNewWorld ) ;
  198.                     (void) LockPixels( offPixMap ) ;
  199.                     CopyBits( &((GrafPtr)theNewWorld)->portBits,
  200.                               &window->portBits,
  201.                               &window->portRect,
  202.                               &window->portRect,
  203.                               srcCopy,
  204.                               nil ) ;
  205.                     (void) UnlockPixels( offPixMap ) ;
  206.  
  207.                     EndUpdate( window );
  208.                     SetPort( oldPort ) ;
  209.                     break ;
  210.                     
  211.                 case keyDown:
  212.                 case autoKey:
  213.                     HandleKeyPress(&event);
  214.                     break;
  215.                     
  216.                 case diskEvt:
  217.                     if ( HiWrd(event.message) != noErr ) 
  218.                         (void) DIBadMount(aPoint, event.message);
  219.                     break;
  220.                     
  221.                 case osEvt:
  222.                 case activateEvt:
  223.                     break;
  224.  
  225.  
  226.             }
  227.         }
  228.     }
  229. }
  230.  
  231.  
  232. void HandleKeyPress(EventRecord *event)
  233. {
  234.     char    key;
  235.  
  236.     key = event->message & charCodeMask;
  237.     
  238.     // just check to see if we want to quit...
  239.     
  240.     if ( event->modifiers & cmdKey ) {        /* Command key down? */
  241.         HandleMenuCommand(MenuKey(key));
  242.     } 
  243. }
  244.  
  245.  
  246. void HandleMenuCommand(long menuResult)
  247. {
  248.     short        menuID;
  249.     short        menuItem;
  250.     Str255        daName;
  251.     DialogPtr    theDialog ; 
  252.     short        itemHit ;
  253.     SFTypeList    myTypes = { 'PICT' } ;
  254.     FSSpec        theFSSpec ;
  255.     PicHandle    thePicture ;
  256.     OSErr        err ;
  257.     short        theRef ;
  258.     
  259.     StandardFileReply    theSFReply ;
  260.  
  261.     menuID = HiWrd(menuResult);
  262.     menuItem = LoWrd(menuResult);
  263.     switch ( menuID ) {
  264.         case mApple:
  265.             switch ( menuItem ) {
  266.                 case iAbout:
  267.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  268.                     do {
  269.                         ModalDialog ( nil, &itemHit );
  270.                     } while( itemHit != ok ) ;
  271.                     DisposDialog ( theDialog );
  272.                     break;
  273.                     
  274.                 default:
  275.                     GetItem(GetMHandle(mApple), menuItem, daName);
  276.                     (void) OpenDeskAcc(daName);
  277.                     break;
  278.             }
  279.             break;
  280.         case mFile:
  281.             switch ( menuItem ) {
  282.                 case iOpen:
  283.                     // Get the file name to open
  284.                     StandardGetFile( nil, 1, myTypes, &theSFReply ) ;
  285.                     
  286.                     // did the user cancel?
  287.                     if(!theSFReply.sfGood)
  288.                         break ;
  289.                     
  290.                     // open the file
  291.                     err = FSpOpenDF( &theSFReply.sfFile, fsRdPerm, &theRef ) ;
  292.                     
  293.                     if( err != noErr )
  294.                         break ;     // should handle this properly
  295.                         
  296.                     thePicture = DoReadPICT( theRef, &err ) ;
  297.                     
  298.                     if( err != noErr )
  299.                         break ;     // should handle this properly
  300.                 
  301.                     // display the contents
  302.                     err = DoCreateWindow( thePicture ) ;
  303.                     
  304.                     break ;
  305.                     
  306.                 case iClose:
  307.                     DisposeWindow ( FrontWindow() );
  308.                     break ;
  309.                 case iQuit:
  310.                     gQuitFlag = true;
  311.                     break;
  312.             }
  313.             break;
  314.             
  315.         case mPalette:
  316.             switch ( menuItem ) {
  317.                 case iUsePictPalette :
  318.                     // toggle the check mark and the global boolean
  319.                     gUsePictPalette = !gUsePictPalette ;
  320.                     CheckItem ( GetMHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  321.                     break ;
  322.             }
  323.             break ;
  324.             
  325.         case 131:
  326.             if( menuItem == 1 )
  327.                 if( FrontWindow() != nil )
  328.                     ;    // add test code here
  329.                     
  330.             break; 
  331.  
  332.     }
  333.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  334. }
  335.  
  336. void AdjustMenus( void ) 
  337. {
  338.     WindowPtr    theWindow ;
  339.     theWindow = FrontWindow() ;
  340.     if( theWindow != nil ) {
  341.         EnableItem ( GetMHandle ( mFile ), iClose );
  342.     }
  343.     else {
  344.         DisableItem ( GetMHandle ( mFile ), iClose );
  345.     }
  346.     // make sure the check marks are correct
  347.     CheckItem ( GetMHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  348. }
  349.  
  350. PicHandle DoReadPICT( short theRef, OSErr *theErr ) 
  351. {
  352.     long        theFileSize ;
  353.     PicHandle    thePicture ;
  354.     
  355.     // pict files have a 512 byte header at the front - we dont care about this
  356.     // we can find the size of the pict by subtracting 512 bytes from the length
  357.     // of the file.  We then want to resize the handle to that and read the data
  358.     // into the resized handle.
  359.     
  360.     if(( *theErr = GetEOF( theRef, &theFileSize )) != noErr ) {
  361.         FSClose( theRef ) ;
  362.         return nil ; 
  363.     }
  364.     
  365.     if(( *theErr = SetFPos( theRef, fsFromStart, 512)) != noErr ) {
  366.         FSClose( theRef ) ;
  367.         return nil ; 
  368.     }
  369.  
  370.     theFileSize -= 512 ;
  371.     
  372.     thePicture = (PicHandle)NewHandle( theFileSize ) ;
  373.     if( thePicture == nil ) {
  374.         FSClose( theRef ) ;
  375.         *theErr = MemError() ;
  376.         return nil ;         // what ever the mem manager error was
  377.     }
  378.     
  379.     HLock( (Handle)thePicture ) ;
  380.     *theErr = FSRead( theRef, &theFileSize, (Ptr)*thePicture ) ;
  381.     HUnlock(  (Handle)thePicture ) ;
  382.     
  383.     if( *theErr != noErr ) {
  384.         FSClose( theRef ) ;
  385.         return nil ; 
  386.     }
  387.  
  388.     return thePicture ;    
  389. }
  390.  
  391. OSErr DoCreateWindow( PicHandle thePicture )
  392. {
  393.  
  394.     Rect        theRect ;
  395.     OSErr        theErr ;
  396.     GWorldPtr    theNewWorld ;
  397.     CGrafPtr    savedPort ;
  398.     GWorldPtr    savedGWorld ;
  399.     WindowPtr    theWindow ;
  400.     GDHandle    oldDevice ;
  401.     
  402.     PictInfo        thePictInfo ;
  403.     PaletteHandle    thePictPalette = nil ;
  404.     CTabHandle        thePictCTab = nil ;
  405.     
  406.     // make an offscreen environment and image the pict into this
  407.     // Make a window the size of the pict
  408.     // store a reference to the GWorld in the Refcon of the window
  409.     // invalidate the window content area.
  410.     
  411.     theRect.top = (**thePicture).picFrame.top ;
  412.     theRect.left = (**thePicture).picFrame.left ;
  413.     theRect.bottom = (**thePicture).picFrame.bottom ;
  414.     theRect.right = (**thePicture).picFrame.right ;
  415.     
  416.     // to we want to attempt to sample the picture... 
  417.     if( gUsePictPalette ) {
  418.     
  419.         // use the picture utilities to get the palette for the window
  420.         theErr = GetPictInfo( thePicture, &thePictInfo, returnColorTable, 256, systemMethod, 0) ;
  421.         
  422.         // set up the palette and color table for later use
  423.         thePictPalette = NewPalette( 256, thePictInfo.theColorTable, pmTolerant, 0x1000 ) ;
  424.         thePictCTab = thePictInfo.theColorTable ;
  425.     }
  426.     
  427.     // we are only dealing with eight bit images here
  428.     // hence the requirement for the picture utils package to 
  429.     // return 256 colors, and we will create a gWorld 8 bits deep
  430.     
  431.     theErr = NewGWorld( &theNewWorld, 8, &theRect, thePictCTab, nil, 0L ) ;
  432.     
  433.     if( theErr != noErr ) 
  434.         return theErr ;
  435.     
  436.     // save the world
  437.     GetGWorld( &savedPort, &oldDevice ) ;
  438.     SetGWorld( theNewWorld, nil ) ;
  439.     
  440.     
  441.     RGBForeColor( &kRGBBlack ) ;        // ensure the fg and bg colors are 
  442.     RGBBackColor( &kRGBWhite ) ;        // as anticipated
  443.     EraseRect( &theRect ) ;                // clear the area for the pict
  444.     PenMode( srcCopy ) ;                // ensure the t/f mode is as expected
  445.  
  446.     // render the image into the offscreen buffer
  447.     DrawPicture( thePicture, &theRect ) ;
  448.     
  449.     SetGWorld( savedPort, oldDevice ) ;
  450.     
  451.     // create the window
  452.     OffsetRect( &theRect, gStaggerPos.h, gStaggerPos.v) ;
  453.     gStaggerPos.h += 16 ;
  454.     gStaggerPos.v += 16 ;        // heh - should roll these around, but you wont 
  455.                                 // create more than a couple of windows, will you  :-)
  456.                                  
  457.     theWindow  = NewCWindow( nil, &theRect, "\pplayTime", true, 
  458.                                 documentProc, (WindowPtr)-1, true, (long)theNewWorld );    
  459.                 
  460.     // and if we set up the palette earlier assign it to the window                
  461.     if( thePictPalette != nil ) {
  462.         SetPalette ( theWindow, thePictPalette, true );
  463.     }
  464.     
  465.     ActivatePalette ( theWindow );    
  466.     
  467.     // make sure it is visible
  468.     ShowWindow( theWindow ) ;
  469.     
  470.     SetGWorld( (CGrafPtr)theWindow, nil ) ;
  471.     
  472.     // invalidate the content region of the window - we don't do any drawing to it here.
  473.     InvalRect ( &theRect );
  474.     
  475.     SetGWorld( savedPort, oldDevice ) ;
  476. }